Rekurzija in OS

Sklop nalog, kjer pišemo funcije, ki naredijo določena opravila z datotekami na nivoju operacijskega sistema. V nalogah bodo potrebne te funkcije:


Pregled map in datotek

Za preverjanje nalog v imenik/mapo, kjer imate rešitve, skopirajte to datoteko ZIP in jo razširite (nastala bo mapa PythonOsRek s podmapami testX in EURO2012)

1. podnaloga

Sestavi funkcijo vrniMape_IskDat(potDoMape,imeDatoteke), ki vrne po abecedi urejen seznam vseh map, ki vsebujejo dano datoteko. Pri tem pot začni opisovati šele pri mapi potDoMape

    izpisiMape_IskDat('.\\PythonOSRek\\test1', 'drevo.py')
    ['.\\PythonOSRek\\test1', '.\\PythonOSRek\\test1\\PodM\\TraRa']

če potDoMape ne opisuje datoteke, vrni None

Uradna rešitev

import os

def vrniMape_IskDat(potDoMape,imeDatoteke):
    '''vrne po abecedi urejen seznam vseh map, ki vsebujejo dano datoteko.'''
    if not os.path.isdir(potDoMape): # ni te mape
        return None       
    seznamMap_IskDat = [] #shranimo poti do iskane datoteke
    if imeDatoteke in os.listdir(potDoMape): # pogledamo datoteke "na vrhu"
        seznamMap_IskDat.append(potDoMape)
    for datoteka in os.listdir(potDoMape):
        ime = potDoMape + "\\" + datoteka
        if os.path.isdir(ime): # gre za mapo
            vPodmapi = vrniMape_IskDat(ime,imeDatoteke)
            seznamMap_IskDat.extend(vPodmapi)
    return sorted(seznamMap_IskDat)

2. podnaloga

Sestavi funkcijo najvecDatVMapi(potDoMape), ki v izbrani mapi (in njenih podmapah) poišče mapo, ki vsebuje največ datotek (ne podmap). Funkcija naj vrne ime iskane mape (skupaj s potjo) ter število datotek v tej mapi. Če je takih map več, vrni prvo po abecedi (upoštevaj polno ime, skupaj s potjo!)

Uradna rešitev

import os

def najvecDatVMapi(mapa):
    ''' Funkcija vrne ime iskane mape (skupaj s potjo)
    ter število datotek v tej mapi. Če je takih map več, vrne prvo po abecedi (upošteva polno
    ime, skupaj s potjo!)'''
    najvecjaIme = mapa
    #prestejemo datoteke v tej mapi
    steviloDatotek = 0
    for trenDat in os.listdir(mapa):
        if os.path.isfile(mapa + "\\" + trenDat):
            steviloDatotek +=1
    najvecjaVelikost = steviloDatotek
    #mapo z najvec datotek primerjamo z naj mapami v podmapah
    seznamMap = [] # naredimo seznam podmap
    for trenMapa in os.listdir(mapa):
        if os.path.isdir(mapa + "\\" + trenMapa):
            seznamMap.append(trenMapa)
    #rekruzivno pregledamo podmape
    for mape in seznamMap:
        najvecjaImeImenik, najvecjaVelikostImenik = najvecDatVMapi(mapa + "\\" + mape)
        #če ima trenutna mapa enako prejsna ni potrebno narediti nič, ker so že po abecedi!
        if najvecjaVelikostImenik > najvecjaVelikost:
            najvecjaVelikost = najvecjaVelikostImenik
            najvecjaIme = najvecjaImeImenik
    return najvecjaIme, najvecjaVelikost

3. podnaloga

Sestavi funkcijo prestejDatoteke(potDoMape), ki prešteje, koliko je vseh datotek v izbrani mapi. Pri tem naj šteje tudi datoteke v podmapah, map pa naj ne šteje. Če potDomape ne opisuje mape, vrni None

Uradna rešitev

import os

def prestejDatoteke(potDoMape):
    ''' Vrne stevilo datotek v mapi in njenih podmapah.'''
    if not os.path.isdir(potDoMape): # ni te mape
        return None    
    steviloDatotek = 0 #prestejemo datoteke
    for trenDat in os.listdir(potDoMape):
        if os.path.isfile(potDoMape + "\\" + trenDat):
            steviloDatotek += 1
        else: # gre za mapo
            steviloDatotek += prestejDatoteke(potDoMape + "\\" + trenDat)
    return steviloDatotek

4. podnaloga

Sestavi funkcijo vrniDatPy(potDoMape), ki vrne po abecedi urejen seznam (polnih)imen vseh datotek v izbrani mapi in njenih podmapah, ki imajo končnico .py.

Uradna rešitev

import os

def vrniDatPy(potDoMape):
    '''Izpise imena vseh datotek (skupaj s potjo), ki imajo koncnico .py.'''
    if not os.path.isdir(potDoMape): # ni te mape
        return None 
    seznamMap_IskDat = [] #shranimo poti do iskane datoteke
    for datoteka in os.listdir(potDoMape): # pogledamo vse datoteke in datoteke v imenikih
        ime = potDoMape + "\\" + datoteka
        if os.path.isfile(ime): # gre za navadno datoteko
            končnica = os.path.splitext(datoteka)[1]
            if končnica == '.py':
                seznamMap_IskDat.append(ime)
        elif os.path.isdir(ime): # gre za mapo
            vPodmapi = vrniDatPy(ime)
            seznamMap_IskDat.extend(vPodmapi)
    return sorted(seznamMap_IskDat)

Briši ...

1. podnaloga

Sestavi funkcijo izbrisiPrazneMape(potDoMape), ki v izbrani mapi (in njenih podmapah) pobriše vse prazne datoteke (tiste z velikostjo 0) in vse prazne mape (tiste, ki ne vsebujejo nobenih datotek ali podmap). Funkcija naj vrne par, ki ga sestavljata število pobrisanih datotek in število pobrisanih map, oziroma None, če potDoMape ne opisuje imenika Pozor: ko zbrišemo prazno datoteko, se lahko sprazni tudi mapa.

Pred testiranjem vedno skopirajte to datoteko ZIP (staro mapo PythonOsRek pobrišite!) in jo razširite (nastala bo mapa PythonOsRek s podmapami testX in EURO2012)

Uradna rešitev

import os

def izbrisiPrazneMape(potDoMape):
    '''Izbriši vse prazne datoteke in prazne mape'''
    kolikoDat, kolikoMap = 0, 0
    if not os.path.isdir(potDoMape): # ni mapa
        return None
    vseDat = os.listdir(potDoMape)
    for datoteka in vseDat:
        #izbrisemo samo prazne datoteke
        if os.path.isfile(potDoMape + "\\" + datoteka) and os.path.getsize(potDoMape + "\\" + datoteka) == 0:
            os.remove(potDoMape + "\\" + datoteka)
            kolikoDat += 1
        elif os.path.isdir(potDoMape + "\\" + datoteka): #filtriramo mape
            kolDat, kolMap = izbrisiPrazneMape(potDoMape + "\\" + datoteka)
            kolikoDat += kolDat
            kolikoMap += kolMap
    #če je mapa sedaj prazna, jo izbrisemo
    if len(os.listdir(potDoMape)) == 0:
        os.rmdir(potDoMape)
        kolikoMap += 1
    return kolikoDat, kolikoMap

Izpisovanje ...

Naloga nima testnega programa! V Tomu so le zato, da so "na kupu"

Vsaka oddaja bo označena kot pravilna!

1. podnaloga

Izpiši mapo

Sestavi funkcijo izpisiDat_izbMapa(potDoMape), ki izpiše vse datoteke v izbrani mapi in njenih podmapah. Funkcija naj izpisuje samo imena datotek, brez poti. Uporabi izpis z zamikanjem, da bo razvidno, kateri mapi pripada katera datoteka. Vedno najprej izpiši datoteke, potem mape

    a.txt
    tra.py
    bla
      dat.txt
    ble
      blu
        c.dat
      xxx
      yyy
        e.dat

Uradna rešitev


      
        

2. podnaloga

Sestavi funkcijo izpisiDatPy(potDoMape), ki izpiše imena vseh datotek v izbrani mapi in njenih podmapah, ki imajo končnico .py. Izpisuje naj polna imena (skupaj s potjo).

Uradna rešitev


      
    
      

Iskanje

Naloge nimajo testnega programa! V Tomu so le zato, da so "na kupu". Vsaka oddaja bo označena kot pravilna!

Če uporabite datotečni strukturo iz datoteke ZIP, kot je opisana pri nalogi Pregled map in datotek, naj se vaše funkcije obnašajo kot kažejo zgledi!

1. podnaloga

Sestavi funkcijo izpisiDatVelikost(potDoMape, velikost), ki vrne seznam polnih imen datotek v dani mapi in njenih podmapah, katerih velikost je večja ali enaka dani vrednosti.

Uradna rešitev


      
        

2. podnaloga

Sestavi funkcijo izpisiMape_IskDat(potDoMape,imeDatoteke), ki izpiše vse mape, ki vsebujejo dano datoteko.

     >>> izpisiMape_IskDat('.\\PythonOSrek', 'drevo.py')
     .\PythonOSrek\test1\drevo.py
     .\PythonOSrek\test1\podM\TraRa\drevo.py
     .\PythonOSrek\test1a\drevo.py
     .\PythonOSrek\test1a\podM\TraRa\drevo.py
     >>>

Uradna rešitev


      
        

3. podnaloga

Sestavi funkcijo najvecDatVMapi(potDoMape), ki v izbrani mapi (in njenih podmapah) poišče mapo, ki vsebuje največ datotek (štejemo samo datoteke v mapi, ne tudi v podmapah, saj je drugače naloga nesmiselna). Funkcija naj vrne ime iskane mape (skupaj s potjo) ter število datotek v tej mapi.

  >>> najvecDatVMapi('.\\PythonOSrek')
  ('.\\PythonOSrek\\test1', 7)
  >>>

Uradna rešitev


      
        

4. podnaloga

Poišči najnovejšo datoteko

Sestavi funkcijo poisciSezZadSprmDat(potDoMape), ki v izbrani mapi (in njenih podmapah) poišče datoteke, ki so bile zadnje spremenjene. Funkcija naj vrne seznam imen teh datotek (skupaj s potjo).

    >>> poisciSezZadSprmDat('.\\PythonOSrek')
    ['.\\PythonOSrek\\EURO2012\\euro database.py']
    >>>

Uradna rešitev


      
        

5. podnaloga

Poišči najnovejšo datoteko

Sestavi funkcijo poisciZadSprmDat(potDoMape), ki v izbrani mapi (in njenih podmapah) poišče datoteko, ki so bile zadnja spremenjena. Funkcija naj vrne po abecedi najmanjše ime izmed teh datotek (skupaj s potjo).

    >>> poisciZadSprmDat('.\\PythonOSrek')
    '.\\PythonOSrek\\EURO2012\\euro database.py'
    >>>

Uradna rešitev


      
        

6. podnaloga

Poišči največjo datoteko

Sestavi funkcijo najvecjaDat(potDoMape), ki v izbrani mapi (in njenih podmapah) poišče največjo datoteko. Funkcija naj vrne par, ki ga sestavljata po abecedi zandje ime take datoteke (skupaj s potjo) in velikost

   >>> najvecjaDat('.\\PythonOSrek')
   ('.\\PythonOSrek\\test1\\Tips.PNG', 94535)
   >>>

Uradna rešitev